#define BIT16 0x1FF
#define BIT11 0x800
#define BIT8 0x100
#define BIT7 0x80
#define BIT0 0x00

#define CPY_FLAGS(flag)     (AF.reg.F & flag)

#define MemReadB(off)		mem->read(off)
#define MemWriteB(off,data)	mem->write(off,data)

#define MemReadW(off)		mem->read(off)
#define MemWriteW(off,data)	mem->write(off,data)

#define MemInc(off)         mem->inc(off)
#define MemDec(off)         mem->dec(off)

#define LD_pp_ii(pp)		pp = MemReadW(++PC.pair); PC.pair += 2; break

#define INC_r(r)			AF.reg.F = SZTable[++r] | (((r)==0x10)?H_FLAG:0) | (((r)==0x80)?P_FLAG:0) | CPY_FLAGS(C_FLAG); ++PC.pair
#define DEC_r(r)			AF.reg.F = SZTable[--r] | (((r)==0x0F)?H_FLAG:0) | (((r)==0x7F)?P_FLAG:0) | CPY_FLAGS(C_FLAG) | (N_FLAG); ++PC.pair


#define LD_r_i(r)           r = MemRead(PC.pair++); break
#define INC_pp(pp)          pp++; break
#define DEC_pp(pp)          pp--; break
#define LD_r_m(r,m)         r = MemRead(m); break

#define INC_m(m)			tmp_b = MemInc(m);	\
							AF.reg.F = SZTable[tmp_b] | CPY_FLAGS(C_FLAG) | (((tmp_b)==0x10)?H_FLAG:0) | (((tmp_b)==0x80)?P_FLAG:0) | CPY_FLAGS(C_FLAG); ++PC.pair

#define DEC_m(m)			tmp_b = MemDec(m);	\
							AF.reg.F = SZTable[tmp_b] | CPY_FLAGS(C_FLAG) | (((tmp_b)==0x0F)?H_FLAG:0) | (((tmp_b)==0x7F)?P_FLAG:0) | CPY_FLAGS(C_FLAG) | (N_FLAG); ++PC.pair

#define EX(a,b)             (a) ^= ((b) ^= ((a) ^= (b)))

#define EX_b(b,m)			b ^= MemReadB(m);	\
							MemWriteB(m,MemReadB(m) ^ b);	\
							b ^= MemReadB(m)

#define EX_pp(high, low)	EX_b(low,SP.pair);	\
							EX_b(high,SP.pair+1);	\
							break

#define AND_(value)			AF.reg.F = SZPTable[(AF.reg.A &= value)] | (H_FLAG)
#define OR_(value)			AF.reg.F = SZPTable[(AF.reg.A |= value)]
#define XOR_(value)			AF.reg.F = SZPTable[(AF.reg.A ^= value)]

#define PUSH(high,low)		MemWriteB(--SP.pair,high); MemWriteB(--SP.pair,low)
#define POP(high,low)		low = MemReadB(SP.pair++); high = MemReadB(SP.pair++)

#define CALL				PUSH(PC.reg.P,PC.reg.C); PC.pair = MemReadW(PC.pair+1)

#define CCALL(cond)			if (cond) { CALL; } else { PC.pair += 3; }

#define JMP					PC.pair = MemReadB(++PC.pair)

#define JR					PC.pair += MemReadB(++PC.pair)+1

#define RST(value)			PUSH(PC.reg.P,PC.reg.C); PC.pair = value

#define ADD_pp(dest,src)	tmp_d = dest + src;	\
							AF.reg.F = CPY_FLAGS(S_FLAG | Z_FLAG | P_FLAG) | (((dest^src^tmp_d) & BIT11)?H_FLAG:0) | ((tmp_d & BIT16)?C_FLAG:0);	\
							dest = tmp_d;	\
							PC.pair += 2

#define ADD_r(value)		tmp_w.pair = AF.reg.A + value;	\
							AF.reg.F = SZTable[tmp_w.reg.low] | (AF.reg.A^value^tmp_w.reg.low) | (((AF.reg.A^tmp_w.reg.low)&(value^tmp_w.reg.low)&BIT7)?P_FLAG:0) | ((tmp_w.pair & BIT8)?C_FLAG:0);	\
							AF.reg.A = tmp_w.reg.low;	\
							++PC.pair;	\
							break

#define SUB_r(value)		tmp_w.pair = AF.reg.A - value;	\
							AF.reg.F = SZTable[tmp_w.reg.low] | (((AF.reg.A^value)&(AF.reg.A^tmp_w.reg.low)&BIT7)?P_FLAG:0) | (AF.reg.A^value^tmp_w.reg.low) | (N_FLAG) | ((tmp_w.pair & BIT8)?C_FLAG:0);	\
							AF.reg.A = tmp_w.reg.low;	\
							++PC.pair;	\
							break

#define CP_(value)			tmp_w.pair = AF.reg.A - value;	\
							AF.reg.F = SZTable[tmp_w.reg.low] | (((AF.reg.A^value)&(AF.reg.A^tmp_w.reg.low)&BIT7)?P_FLAG:0) | (AF.reg.A^value^tmp_w.reg.low) | (N_FLAG) | ((tmp_w.pair & BIT8)?C_FLAG:0);	\
							++PC.pair;	\
							break

#define ADC_(value)			ADD_r(value + (AF.reg.F&BIT0))
#define SBC_(value)			SUB_r(value + (AF.reg.F&C_FLAG))


